package johnkkk.com.obj.buillet;

import android.annotation.SuppressLint;
import android.opengl.GLES32;
import android.opengl.Matrix;
import android.os.Build;
import android.support.annotation.RequiresApi;

import com.graphics.GLGraphics;
import com.graphics.element.AbsSceneNode;
import com.math3d.Mat4;
import com.system.Shader;
import com.tools.GLBufferTools;
import com.tools.SizeOf;
import com.tools.TextureTools;

import java.nio.FloatBuffer;

/**
 * Created by JhonKkk on 2018/11/18.
 */

public class BulletBox extends AbsSceneNode {
    private float vertices[] = {
            // Positions // Normals // Texture Coords
            -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
            0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
            0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
            0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
            -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,
            -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
            -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
            0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
            0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
            0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
            -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
            -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
            -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
            -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
            -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
            -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
            -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
            -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
            0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
            0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
            0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
            0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
            0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
            0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
            -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
            0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f,
            0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
            0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
            -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
            -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
            -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
            0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
            0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
            0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
            -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
            -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f };
    private int[] mBoxVAO;
    private Shader mBoxShader;
    private Mat4 mMat4;
    private int mTex2Ds[];
    @SuppressLint("NewApi")
    public BulletBox(String name) {
        super(name);
        mMat4 = new Mat4();
        //shader
        mBoxShader = new Shader("material_vs.glsl", "material_fs.glsl");
        GLES32.glUseProgram(mBoxShader.mShaderProgram);
        GLES32.glUniformBlockBinding(mBoxShader.mShaderProgram, GLES32.glGetUniformBlockIndex(mBoxShader.mShaderProgram, "MATRIX"), 0x001);
        //配置材质
        GLES32.glUniform1i(GLES32.glGetUniformLocation(mBoxShader.mShaderProgram, "material.diffuseColor"), 0);          //绑定纹理单元0
        GLES32.glUniform1i(GLES32.glGetUniformLocation(mBoxShader.mShaderProgram, "material.specularColor"), 1);          //绑定纹理单元1
        GLES32.glUniform2f(GLES32.glGetUniformLocation(mBoxShader.mShaderProgram, "material.shine"), 32.0f, 0.0f);
        //配置光
        GLES32.glUniform3f(GLES32.glGetUniformLocation(mBoxShader.mShaderProgram, "light.ambientStrength"), 0.1f, 0.1f, 0.1f);
        GLES32.glUniform3f(GLES32.glGetUniformLocation(mBoxShader.mShaderProgram, "light.diffuseStrength"), 0.5f, 0.5f, 0.5f);
        GLES32.glUniform3f(GLES32.glGetUniformLocation(mBoxShader.mShaderProgram, "light.specularStrength"), 1.0f, 1.0f, 1.0f);
        GLES32.glUseProgram(0);
        //fb
        FloatBuffer fb = GLBufferTools.getFloatBuffer(vertices);
        mBoxVAO = new int[1];
        int[] vbo = new int[1];
        GLES32.glGenBuffers(1, vbo, 0);
        GLES32.glGenVertexArrays(1, mBoxVAO, 0);
        GLES32.glBindVertexArray(mBoxVAO[0]);
        GLES32.glBindBuffer(GLES32.GL_ARRAY_BUFFER, vbo[0]);
        GLES32.glBufferData(GLES32.GL_ARRAY_BUFFER, fb.limit() * 4, fb, GLES32.GL_STATIC_DRAW);
        GLES32.glVertexAttribPointer(0x001, 3, GLES32.GL_FLOAT, false, 8 * SizeOf.S_FLOAT_SIZE, 0);
        GLES32.glEnableVertexAttribArray(0x001);
        GLES32.glVertexAttribPointer(0x002, 3, GLES32.GL_FLOAT, false, 8 * SizeOf.S_FLOAT_SIZE, 3 * SizeOf.S_FLOAT_SIZE);
        GLES32.glEnableVertexAttribArray(0x002);
        GLES32.glVertexAttribPointer(0x003, 2, GLES32.GL_FLOAT, false, 8 * SizeOf.S_FLOAT_SIZE, 6 * SizeOf.S_FLOAT_SIZE);
        GLES32.glEnableVertexAttribArray(0x003);
        GLES32.glBindBuffer(GLES32.GL_ARRAY_BUFFER, 0);
        GLES32.glBindVertexArray(0);
        //textures
        mTex2Ds = new int[2];
        mTex2Ds[0] = TextureTools.genSimplerTexture(GLES32.GL_TEXTURE_2D, "textures/container2.png");
        mTex2Ds[1] = TextureTools.genSimplerTexture(GLES32.GL_TEXTURE_2D, "textures/container2_specular.png");
    }

    @Override
    public boolean equals(Object obj) {
        return super.equals(obj);
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    @Override
    public void render(float exTime) {
        super.render(exTime);
        GLES32.glActiveTexture(GLES32.GL_TEXTURE0);
        GLES32.glBindTexture(GLES32.GL_TEXTURE_2D, mTex2Ds[0]);
        GLES32.glActiveTexture(GLES32.GL_TEXTURE1);
        GLES32.glBindTexture(GLES32.GL_TEXTURE_2D, mTex2Ds[1]);
        GLES32.glUseProgram(mBoxShader.mShaderProgram);
        //设置光源位置
        GLES32.glUniform3f(GLES32.glGetUniformLocation(mBoxShader.mShaderProgram, "lightPos"), 3.0f, -1.0f, -3.0f);
        //设置物体位置
        mMat4.normalize();
        //设置视点位置
        GLES32.glUniform3f(GLES32.glGetUniformLocation(mBoxShader.mShaderProgram, "viewPos"), GLGraphics.getCamera().eye.getVec()[0], GLGraphics.getCamera().eye.getVec()[1], GLGraphics.getCamera().eye.getVec()[2]);
        Matrix.translateM(mMat4.mMat4, 0, 0.0f, 0.0f, -5.0f);
        GLES32.glUniformMatrix4fv(GLES32.glGetUniformLocation(mBoxShader.mShaderProgram, "m_matrix"), 1, false, mMat4.getFloatBuffer());
        GLES32.glBindVertexArray(mBoxVAO[0]);
        GLES32.glDrawArrays(GLES32.GL_TRIANGLES, 0, 36);
        GLES32.glBindVertexArray(0);
        GLES32.glUseProgram(0);
        GLES32.glActiveTexture(GLES32.GL_TEXTURE0);
        GLES32.glBindTexture(GLES32.GL_TEXTURE_2D, 0);
        GLES32.glActiveTexture(GLES32.GL_TEXTURE1);
        GLES32.glBindTexture(GLES32.GL_TEXTURE_2D, 0);
    }

    @Override
    public void update(float exTime) {
        super.update(exTime);
    }
}

